package httpclient

import (
	"context"
	"encoding/json"
	"fmt"
	"golang.org/x/net/proxy"
	"log"
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
)

// KlineResult 定义请求结果结构体，适应新的数据格式
type KlineResult struct {
	Ch     string `json:"ch"`
	Status string `json:"status"`
	Ts     int64  `json:"ts"`
	Data   []struct {
		ID     int64   `json:"id"`
		Open   float64 `json:"open"`
		Close  float64 `json:"close"`
		Low    float64 `json:"low"`
		High   float64 `json:"high"`
		Amount float64 `json:"amount"`
		Vol    float64 `json:"vol"`
		Count  int64   `json:"count"`
	} `json:"data"`
}

// GetLastPriceInfo 发起 HTTP 请求获取数据
func GetLastPriceInfo(apiSymbol string, proxyURL string) (map[string]string, error) {
	coinapi := fmt.Sprintf("https://api.huobi.pro/market/history/kline?period=1day&size=1&symbol=%s", apiSymbol)
	var dialer proxy.Dialer
	var err error
	if proxyURL != "" {
		u, err := url.Parse(proxyURL)
		if err != nil {
			log.Printf("Failed to parse proxy URL %s: %v", proxyURL, err)
			return nil, err
		}
		if u.Scheme == "socks5" {
			dialer, err = proxy.SOCKS5("tcp", u.Host, nil, proxy.Direct)
			if err != nil {
				log.Printf("Failed to create SOCKS5 dialer: %v", err)
				return nil, err
			}
		} else {
			dialer = proxy.Direct
		}
	} else {
		// 尝试从环境变量获取 SOCKS5 代理
		socks5ProxyURL := "socks5://127.0.0.1:7890" // 根据实际情况修改
		u, err := url.Parse(socks5ProxyURL)
		if err != nil {
			log.Printf("Failed to parse proxy URL %s: %v", socks5ProxyURL, err)
			return nil, err
		}
		dialer, err = proxy.SOCKS5("tcp", u.Host, nil, proxy.Direct)
		if err != nil {
			log.Printf("Failed to create SOCKS5 dialer: %v", err)
			return nil, err
		}
	}
	tr := &http.Transport{
		// 强制使用 IPv4 进行 DNS 解析
		DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
			d := net.Dialer{
				Resolver: &net.Resolver{
					PreferGo: true,
					Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
						d := net.Dialer{}
						return d.DialContext(ctx, "udp", "8.8.8.8:53") // 使用 Google DNS
					},
				},
			}
			return d.DialContext(ctx, "tcp4", addr)
		},
	}
	if dialer != proxy.Direct {
		tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
			return dialer.Dial(network, addr)
		}
	}
	method := "GET"
	timeOut := 60 * time.Second
	httpClient := http.Client{
		Transport: tr,
		Timeout:   timeOut,
	}
	method = strings.ToUpper(method)
	req, err := http.NewRequest(method, coinapi, nil)
	if err != nil {
		log.Printf("Failed to create request for %s: %v", apiSymbol, err)
		return nil, err
	}
	// 添加必要的请求头
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
	req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7")
	req.Header.Set("Connection", "keep-alive")
	resp, err := httpClient.Do(req)
	if err != nil {
		log.Printf("Failed to send request for %s: %v", apiSymbol, err)
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		log.Printf("Request for %s failed with status code %d", apiSymbol, resp.StatusCode)
		return nil, fmt.Errorf("request failed with status code %d", resp.StatusCode)
	}
	var result KlineResult
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		log.Printf("Failed to decode response for %s: %v", apiSymbol, err)
		return nil, err
	}
	fmt.Println(result)
	return processPriceData(result, apiSymbol)
}

func Req2() {
	//headerOpt := map[string]string{
	//	"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
	//	"Accept":     "gzip, deflate, br, zstd",
	//}
	//ret, err := util.ApiCall("GET", coinapi, nil, headerOpt, 60*time.Second)
	//if err != nil {
	//	log.Printf("Failed to send request for %s: %v", apiSymbol, err)
	//	return nil, err
	//}
	//fmt.Println(ret)
	//var result KlineResult
	//if err := json.Unmarshal(ret.Data, &result); err != nil {
	//	log.Printf("Failed to decode response for %s: %v", apiSymbol, err)
	//	return nil, err
	//}
}
